const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");

const commonCssLoader = 
[
    MiniCssExtractPlugin.loader, 
    'css-loader',
    // {
    //     /**
    //      * css兼容性处理：postcss --> postcss-loader postcss-preset-env
    //      * postcss-loader的作用：帮postcss找到package.json中browserslist里面的配置，通过配置加载指定的css兼容性样式
    //      * postcss是基于node.js运行的一个处理css的工具
    //      * 为什么要用postcss：因为css3的新特性还没有被所有的浏览器支持，所以需要用postcss来处理css兼容性
    //      */
    //     loader: 'postcss-loader',
    //     options: {
    //         ident: 'postcss', // 唯一标识
    //         plugins: () => [
    //             // postcss的插件,帮postcss找到package.json中browserslist里面的配置，通过配置加载指定的css兼容性样式
    //             require('postcss-preset-env')()
    //         ]
    //     }
    // }
]
/**
 * 缓存：
 * 1.babel缓存
 *   cacheDirectory: true
 *  --> 让第二次打包构建速度更快
 * 2.文件资源缓存
 *  hash: 每次wepack构建时会生成一个唯一的hash值
    *  问题：因为js和css同时使用一个hash值
    *  如果重新打包，会导致所有缓存失效
* chunkhash: 根据chunk生成的hash值。如果打包来源于同一个chunk，那么hash值就一样
    * 问题：js和css的hash值还是一样的
    * 因为css是在js中被引入的，所以同属于一个chunk
* contenthash: 根据文件的内容生成hash值。不同文件hash值一定不一样
    * 问题：当文件内容变化，contenthash一定变化
    * 
* chunk是指webpack打包过程中，代码分割出来的代码块
 */
module.exports = {
    entry: './src/index.js',
    // entry: {
    //     index: './src/index.js',
    //     test: './src/test.js'
    // },
    output: {
        filename: 'js/built.[contenthash:10].js',
        path: resolve(__dirname, 'dist')
    },
    // 生产环境下会自动压缩js代码
    mode: 'production',
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html',
            minify: {
                collapseWhitespace: true,
                removeComments: true
            }
        }),
        new MiniCssExtractPlugin({
            filename: 'css/built.css'
        })
    ],
    module: {
        rules: [
            // MiniCssExtractPlugin.loader取代style-loader.作用:提取js中的css成单独文件
            {
                test: /\.css$/,
                use: [...commonCssLoader]
            },
            {
                test: /\.less$/,
                use: [...commonCssLoader, 'less-loader']
            },
            {
                test: /\.(jpg|png|gif)$/,
                loader: 'url-loader',
                options: {
                    limit: 8 * 1024, // 图片大小小于8kb，就会被base64处理
                    name: '[hash:10].[ext]', // 取图片的hash的前10位，取图片原来的扩展名
                    outputPath: 'imgs'
                }
            },
            {
                // 处理html中的img图片(负责引入img，从而能被url-loader进行处理)
                test: /\.html$/,
                loader: 'html-loader'
            },
            {
                exclude: /\.(html|js|css|less|jpg|png|gif)$/,
                loader: 'file-loader',
                options: {
                    outputPath: 'media'
                }
            },
            /**
             * eslint-loader: eslint检查代码
             * babel-loader @babel/core : js兼容性处理
             * 1.基本js兼容性处理 --> @babel/preset-env
             * 问题：只能转换基本语法，如promise不能转换
             * 2.全部js兼容性处理 --> @babel/polyfill
             * 问题：我只要解决部分兼容性问题，但是将所有兼容性代码全部引入，体积太大了
             * 3.需要做兼容性处理的就做：按需加载 --> core-js
             */
            {
                test: /\.js$/,
                exclude: /node_modules/,
                enforce: 'pre', // 优先执行
                loader: 'eslint-loader',
                options: {
                    // 自动修复eslint的错误
                    fix: true
                }
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                       presets:  [
                            [
                                '@babel/preset-env',
                                {
                                    useBuiltIns: 'usage',
                                    corejs: { version: 3 },
                                    targets: {
                                    chrome: '60',
                                    firefox: '60',
                                    ie: '9',
                                    safari: '10',
                                    edge: '17'
                                    }
                                }
                            ]
                       ],
                    //    开启babel缓存,让第二次构建时，会读取之前的缓存
                       cacheDirectory: true
                    }
                }
            }
        ]
    },
    /**
     * CssMinimizerPlugin: 压缩css
     */
    optimization: {
        minimize: true,
        minimizer: [
            new CssMinimizerPlugin({
                filename: 'css/built.[contenthash].css'
            })
        ]
    },
    /**
     * devServer: 开发服务器，用来自动化(自动编译，自动打开浏览器，自动刷新浏览器),不能用于生产环境
     * contentBase: 打包后的文件路径
     * compress: 启动gzip压缩
     * hot: 开启HMR功能
     */
    devServer: {
        contentBase: resolve(__dirname, 'dist'),
        compress: true, // 启动gzip压缩
        port: 3000,
        open: true,
        hot: true // 开启HMR功能
    },
}